package com.blog.aspect;

import com.alibaba.fastjson.JSON;
import com.blog.annotation.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**切面类
 *
 */
@Component
@Aspect
@Slf4j
public class LogAspect {

	@Pointcut("@annotation(com.blog.annotation.SystemLog)")
	public void pt(){
	}


	@Around("pt()")
	public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {

		Object proceed;
		try {
			handlebefore(joinPoint);
			proceed = joinPoint.proceed();
			handleafter(proceed);
		} finally {
			// 结束后换行
			log.info("=======End=======" + System.lineSeparator());
		}

		return proceed;
	}

	/**方法执行之后
	 *
	 */
	private void handleafter(Object proceed) {
		// 打印出参
		log.info("Response        :{}", JSON.toJSON(proceed));

	}

	/**方法执行之前
	 *
	 */
	private void handlebefore(ProceedingJoinPoint joinPoint) {

		ServletRequestAttributes requestAttributes =
				(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request =
				requestAttributes.getRequest();

		//获取被增强方法上的注解对象
		SystemLog systemLog = getSystemLog(joinPoint);
		log.info("=======Start=======");
		// 打印请求 URL
		log.info("URL             :{}", request.getRequestURI());
		// 打印描述信息
		log.info("BusinessName    :{}", systemLog.businessName());
		// 打印 Http method
		log.info("HTTP Method     :{}", request.getMethod());
		// 打印调用 controller 的全路径以及执行方法
		log.info("Class Method    :{},{}",joinPoint.getSignature().getDeclaringTypeName(),((MethodSignature) joinPoint.getSignature()).getName());
		// 打印请求的 IP
		log.info("IP              :{}",request.getRemoteHost());
		// 打印请求入参
		log.info("Request Args    :{}", JSON.toJSON(joinPoint.getArgs()));
		/*// 打印出参
		log.info("Response        :{}", );*/

	}

	private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) {

		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

		SystemLog annotation = methodSignature.getMethod().getAnnotation(SystemLog.class);

		return annotation;
	}

}
